package com.ifinc.common.protocol.i8583.field;

import com.ifinc.common.protocol.i8583.I8583Request;
import com.ifinc.common.utils.StringUtils;
import com.ifinc.common.utils.encode.ByteUtil;

import java.io.UnsupportedEncodingException;

/**
 * User: luotao
 * Date: 13-11-15
 * Time: 13:39
 */
public abstract class AbstractField implements Field {

    protected String encoding = "GBK";

    protected byte[] srcBytes = new byte[]{};

    protected String srcValue;

    protected byte[] resBytes = new byte[]{};

    protected String resValue;

    protected boolean joinBitMap = true;

    protected I8583Request i8583Request;

    protected int fieldLen = 0;

    public int getFieldLen() {
        return fieldLen;
    }

    public void setFieldLen(int fieldLen) {
        this.fieldLen = fieldLen;
    }

    protected AbstractField() {
    }

    public AbstractField(int fieldLen) {
        this(fieldLen, true);
    }

    public AbstractField(int fieldLen, boolean joinBitMap) {
        this.fieldLen = fieldLen;
        this.joinBitMap = joinBitMap;
    }

    public byte[] getResBytes() {
        return resBytes;
    }


    public String getResValue() {
        return resValue;
    }

    public void setResValue(String resValue) {
        this.resValue = resValue;
    }

    protected Integer fieldId;

    public Integer getFieldId() {
        return fieldId;
    }

    public void setFieldId(Integer fieldId) {
        this.fieldId = fieldId;
    }

    public void setResBytes(byte[] resBytes) {
        this.resBytes = resBytes;
    }

    public abstract byte[] toByte();


    public abstract byte[] toMacByte();

    public String getEncoding() {
        return encoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public byte[] getSrcBytes() {
        return srcBytes;
    }

    public void setSrcBytes(byte[] srcBytes) {
        this.srcBytes = srcBytes;
    }

    @Override
    public void setSrcValue(String srcValue) {
        this.srcValue = srcValue;
        srcBytes = str2byte(srcValue);
        setSrcBytes(srcBytes);
        setResBytes(srcBytes);
    }

    public byte[] str2byte(String str) {
        try {
            byte[] byteData = str.getBytes(getEncoding());
            return byteData;
        } catch (UnsupportedEncodingException e) {
            return srcValue.getBytes();
        }
    }

    public String byte2Str(byte[] bytes) {
        try {
            return new String(bytes, getEncoding());
        } catch (UnsupportedEncodingException e) {
            return new String(bytes);
        }
    }

    @Override
    public void setProtocol(I8583Request i8583Request) {
        this.i8583Request = i8583Request;
    }

    public String getSrcValue() {
        return srcValue;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append(StringUtils.STR_LEFT_SPLIT1);
        builder.append(" fieldId :" + getFieldId());
        builder.append(",fieldType:" + getFieldType());
        builder.append(",srcValue:" + getSrcValue());
        builder.append(",resValue:" + getResValue());
        builder.append(",encoding:" + getEncoding());
        builder.append(",srcBytes:" + ByteUtil.showByteStr(getSrcBytes()));
        builder.append(",resBytes:" + ByteUtil.showByteStr(getResBytes()));
        builder.append(StringUtils.STR_RIGHT_SPLIT1);
        return builder.toString();
    }

    @Override
    public boolean isAutoFill() {
        return false;
    }

    public boolean joinBitMap() {
        return joinBitMap;
    }

    @Override
    public void verify() {
    }

    public byte[] setResDataInfo(byte[] bytes) {
        setResBytes(bytes);
        setResValue(byte2Str(bytes));
        return bytes;
    }

    public byte[] setResDataInfo(String str) {
        byte[] bb = str2byte(str);
        setResBytes(bb);
        setResValue(str);
        return bb;
    }

    public int getEncodeLen(){
        return fieldLen;
    }
}
